package com.daxue.lcm.api.grpc.client;

import com.daxue.lcm.api.grpc.config.GrpcServiceInfo;
import io.grpc.Channel;
import io.grpc.Metadata;
import io.grpc.stub.AbstractStub;

import java.beans.ConstructorProperties;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

/**
 * @author daxue0929
 * @date 2022/9/28
 */

public abstract class AbstractGrpcServiceClient<T extends AbstractStub<T>> {

    public static final Metadata.Key<String> MDC_HEADER_KEY;
    private final Channel channel;
    private final GrpcServiceInfo serviceInfo;
    private T stub;

    protected T getStub() {
        T t = Optional.ofNullable(this.stub).orElseGet(() -> {
            return this.stub = this.genStub(this.channel);
        });
        T t1 = t.withDeadlineAfter(this.serviceInfo.getStub().getDeadline().toNanos(), TimeUnit.NANOSECONDS);
        return t1;
    }

    //待实现的方法。
    protected abstract T genStub(Channel channel);

    @ConstructorProperties({"channel", "serviceInfo"})
    public AbstractGrpcServiceClient(final Channel channel, final GrpcServiceInfo serviceInfo) {
        this.channel = channel;
        this.serviceInfo = serviceInfo;
    }

    static {
        MDC_HEADER_KEY = Metadata.Key.of("mdc", Metadata.ASCII_STRING_MARSHALLER);
    }
}
